
import Painter from './selectSceneRm3';
import { State } from './state';
import { Bonus } from './bonus';
import { Tracker } from './tracker';

/**
 * this.context.assetPath('img/1.jpg')
 */

class SelectApp {

	/** @type { Tracker } */
	tracker = null;
	/** @type { Bonus } */
	bonus = null;

	constructor (context) {
		this.context = context;
		this.state = global.state = new State();

		const font = new window.FontFace('PressStart', `url(${context.assetPath('show/PressStart2P-Regular.woff.ttf')})`);
		document.fonts.add(font);
		this.fontLoaded = font.load();

		// 默认配置写这里
		this.state.frames[0].avatar = 'spark';
		this.state.frames[1].avatar = 'snake';
		this.state.frames[2].avatar = 'needle';
		this.state.frames[3].avatar = 'top';
		this.state.frames[4].avatar = 'shadow';
		this.state.frames[5].avatar = 'magnet';
		this.state.frames[6].avatar = 'gemini';
		this.state.frames[7].avatar = 'hard';

		this.state.frames[0].title = 'SPARK MAN'; // SPARK MAN
		this.state.frames[1].title = 'SNAKE MAN';
		this.state.frames[2].title = 'NEEDLE MAN';
		this.state.frames[3].title = 'TOP MAN';
		this.state.frames[4].title = 'SHADOW MAN';
		this.state.frames[5].title = 'MEGNET MAN';
		this.state.frames[6].title = 'GEMINI MAN';
		this.state.frames[7].title = 'HARD MAN';

		global.myapp = this;
	}

	init (libs) {
		// this.handler = new Handler({
		// 	pixi : libs.pixi,
		// 	// 调用方法: assetPath('img/1.jpg')
		// 	assetPath : this.context.assetPath,
		// 	sendStatus : () => this.sendStatus(),
		// });
		this.tracker = new Tracker({
			assetPath : this.context.assetPath,
			sound : libs.sound
		}, 0.5, 0.3);
		this.bonus = new Bonus(this.state, () => this.onBonusStop(), () => this.tracker.playSe());

		this.fontLoaded.then(() => {
			this.painter = new Painter({
				PIXI : libs.pixi,
				assetPath : this.context.assetPath,
				state : this.state,
				ticker : (time) => this.tick(time),
				events : {
					cursorMove : (index) => this.cursorMove(index),
				}
			});
		});
	}

	destroy () {
		//
	}

	sendStatus () {
		// nothing, 等待被覆盖
	}
	
	collectInfo () {
		let raw = this.state.extract();

		// 补充: 是否摇奖在停止的过程中
		raw.waitForStop = this.bonus.waitForStop;
		// 补充: 背景音乐的音频启用
		raw.audioVolume = this.tracker.getAudioVolume();
		// 补充: 音效的音频启用
		raw.seVolume = this.tracker.getSeVolume();

		return raw;
	}

	onMessage (key, data) {
		switch (key) {
			case 'updateFrame': {
				// 修改范围包括：
				// 1. Boss avatar (可以是 null)
				// 2. Boss title
				// 结构：
				/*
				 * {
				 * 	 frames: []
				 * }
				 */
				if (!data) {
					break;
				}
				this.updateFrame(data);
				this.sendStatus();
			} break;

			case 'changeCursor': {
				if (data && typeof(data.cursor) === 'number' && data.cursor >= -1 && data.cursor <= 8) {
					this.cursorMove(parseInt(data.cursor));
				} 
			} break;

			case 'updateAnime': {
				// 修改动画状态, 可以:
				// 1. 到启动动画前，暂停: open=2
				// 2. 到启动动画前，播放: open=1
				// 3. 跳过启动动画: open=0
				if (data) {
					this.updateAnime(data);
				} 
			} break;

			// 修改界面标题
			case 'updateThemeTitle': {
				if (data && (typeof(data.normal) === 'string' || typeof(data.round) === 'string')) {
					if (typeof(data.normal) === 'string') {
						this.theme.normal = data.normal;
					}
					if (typeof(data.round) === 'string') {
						this.theme.round = data.round;
					}
					this.sendStatus();
				} 
			} break;

			case 'startRound': {
				// 开始抽奖哦
				// 启动时会通知后台一次
				// 之后修改 cursor 将不会通知后台
				if (this.isInSelectStage()) {
					this.bonus.start();
					this.painter.onRoundStart();
				}
				this.sendStatus();
			} break;

			case 'endRound': {
				// 结束抽奖，但是不会立即暂停，会逐渐停下来
				// 停下来后会通知后台
				this.bonus.stop();
				this.sendStatus();
			} break;

			case 'audioVolume': {
				// 背景音乐 / 音效播放？音量
				if (data && (typeof(data.audio) === 'number' || typeof(data.se) === 'number')) {
					if (data.audio != undefined) {
						let v = data.audio;
						if (v < 0 || !isFinite(v)) {
							v = 0;
						} else if (v > 1) {
							v = 1;
						}
						this.tracker.setVolume(v);
					}
					if (data.se != undefined) {
						let v = data.se;
						if (v < 0 || !isFinite(v)) {
							v = 0;
						} else if (v > 1) {
							v = 1;
						}
						this.tracker.setSeVolume(v);
					}
					// TODO 音效
					this.sendStatus();
				}
			} break;
		}
	}

	updateAnime (data) {
		if (typeof(data.open) === 'number') {
			const oldOpen = this.state.anime.open;
			this.state.anime.open = data.open;
			if (data.open > 0) {
				this.state.anime.selected = 0;
				if (data.open > 1 && oldOpen <= 1) {
					this.onStageStoped();
				}
				if (data.open === 1) {
					if (oldOpen < 1) {
						this.onStageStoped();
					}
					this.onOpenStageBegun();
				}
			}
		} 
		if (typeof(data.selected) === 'number' && this.state.anime.open == 0) {
			// selected
		}
		this.painter.updateAnime();
		this.sendStatus();
	}

	cursorMove (index) {
		this.state.cursor = index;
		// 其它
		this.tracker.playSe();
		this.sendStatus();
	}

	updateFrame (data) {
		if (data.frames && data.frames instanceof Array) {
			let src = this.state.frames;
			let dest = data.frames;
			let dirtMap = [];

			dest.forEach((frame, index) => {
				if (!frame || !(frame instanceof Object) || index >= src.length) {
					dirtMap.push({});
					return;
				}
				let dirt = {};

				// enable
				if (typeof(frame.enable) === 'boolean') {
					src[index].enable = frame.enable;
					dirt.enable = true;
				}

				// title
				if (typeof(frame.title) === 'string') {
					src[index].title = frame.title;
					dirt.title = true;
				}

				// avatar
				if (typeof(frame.avatar) === 'string') {
					src[index].avatar = frame.avatar;
					dirt.avatar = true;
				}

				dirtMap.push(dirt);
			});

			this.painter.updateFrames(dirtMap);
		}
	}

	tick (time) {
		if (this.state.theme == 'rm3') {
			if (this.state.anime.open > 0 && this.state.anime.open <= 1) {
				this.state.anime.open -= time / 64;
				if (this.state.anime.open < 0) {
					this.state.anime.open = 0;
					this.onOpenStageFinished();
				}
			}
		}
		
		// bonus
		this.bonus.tick(time);
	}

	/**
	 * 入场动画结束钩子
	 */
	onOpenStageFinished () {
		this.sendStatus();
	}

	/**
	 * 入场动画开始钩子
	 */
	onOpenStageBegun () {
		this.tracker.play();
		if (this.state.round) {
			this.state.round = false;
		}
		this.state.cursor = -1;
	}

	/**
	 * 动画停止 / stop=2 时触发的钩子
	 */
	onStageStoped () {
		this.tracker.pause();
		if (this.state.round) {
			this.state.round = false;
		}
	}

	onBonusStop () {
		this.painter.onRoundEnd();
		this.sendStatus();
	}

	/**
	 * 询问是否在选择画面.
	 * @returns {boolean}
	 */
	isInSelectStage () {
		return (this.state.anime.open === 0) && (this.state.anime.selected === 0);
	}
}

export default SelectApp;
